import os
import datetime
import json

import pandas as pd

# 默认结果保存根目录
DEFAULT_RESULTS_ROOT = os.getcwd() + "/results/GA/"


def create_stats_list(population, gen):
    """
    创建包含种群个体统计信息的列表。

    参数:
        population: 种群。
        gen: 当前代数。

    返回:
        list: 包含每个个体统计信息的字典列表。
    """
    stats_list = []
    for ind in population:
        tmp_dict = {}
        tmp_dict.update(
            {
                "Generation": gen,
                "obj1": ind.fitness.values[0]
            })
        if hasattr(ind, "objectives"):
            tmp_dict.update(
                {
                    "obj1": ind.objectives[0],
                }
            )
        tmp_dict = {**tmp_dict}
        stats_list.append(tmp_dict)
    return stats_list


def record_stats(gen, population, logbook, stats, verbose, df_list, logging):
    """
    记录当前代数的种群统计信息。

    参数:
        gen: 当前代数。
        population: 种群。
        logbook: DEAP日志记录器。
        stats: DEAP统计信息。
        verbose: 是否打印详细日志。
        df_list: 用于存储DataFrame的列表。
        logging: 日志记录模块。
    """
    stats_list = create_stats_list(population, gen)
    df_list.append(pd.DataFrame(stats_list))
    record = stats.compile(population) if stats is not None else {}
    logbook.record(gen=gen, **record)
    if verbose:
        logging.info(logbook.stream)


def output_dir_exp_name(parameters):
    """
    根据参数生成输出目录和实验名称。

    参数:
        parameters: 配置参数字典。

    返回:
        tuple: 输出目录路径和实验名称。
    """
    if 'experiment_name' in parameters['output'] and parameters['output']['experiment_name'] is not None:
        exp_name = parameters['output']['experiment_name']
    else:
        instance_name = parameters['instance']['problem_instance'].replace('/', '_')[1:]
        instance_name = instance_name.split('.')[0] if '.' in instance_name else instance_name
        population_size = parameters['algorithm'].get('population_size')
        ngen = parameters['algorithm'].get('ngen')
        timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
        exp_name = f"{instance_name}_pop_{population_size}_ngen_{ngen}_{timestamp}"

    if 'folder_name' in parameters['output'] and parameters['output']['folder_name'] is not None:
        output_dir = parameters['output']['folder_name']
    else:
        output_dir = DEFAULT_RESULTS_ROOT
    return output_dir, exp_name


def results_saving(makespan, path, parameters):
    """
    将遗传算法优化结果保存到JSON文件中。

    参数:
        makespan: 最佳解的makespan。
        path: 结果保存路径。
        parameters: 配置参数字典。
    """
    results = {
        "instance": parameters["instance"]["problem_instance"],
        "makespan": makespan,
        "ngen": parameters["algorithm"]["ngen"],
        "population_size": parameters["algorithm"]["population_size"],
        "crossover_rate": parameters["algorithm"]["cr"],
        "mutation_rate": parameters["algorithm"]["indpb"]
    }

    # 如果未提供实验名称，则根据实例和求解时间生成默认实验名称
    os.makedirs(path, exist_ok=True)

    # 将结果保存为JSON文件
    file_path = os.path.join(path, "GA_results.json")
    with open(file_path, "w") as outfile:
        json.dump(results, outfile, indent=4)
